package main

import "fmt"

func main() {
	//1.定义常量
	const PATH string = "/usr/local/go"
	const PI float64 = 3.14
	fmt.Println(PATH)
	fmt.Println(PI)

	//2.尝试修改常量的数值
	//PATH = "/usr/local/php" //cannot assign to PATH

	const internal = "包内可访问" //首字母小写
	const External = "包外可访问" //首字母大写

	//3.定义一组常量
	const C1, C2, C3 = 100, 3.14, "haha"
	const (
		MALE   = 0
		FEMALE = 1
		UNKNOW = 3
	)
	//4.一组常量中，如果某个常量没有初始值，默认和上一行一致
	const (
		a int = 123
		b
		c string = "php"
		d
		e
	)
	fmt.Printf("a: %T,%d\n", a, a)
	fmt.Printf("b: %T,%d\n", b, b)
	fmt.Printf("c: %T,%s\n", c, c)
	fmt.Printf("d: %T,%s\n", d, d)
	fmt.Printf("e: %T,%s\n", e, e)

	//5. 枚举类型：使用常量组作为枚举类型。一组相关数值的数据
	const (
		SPRING = 0
		SUMMER = 1
		AUTUMN = 2
		WINTER = 3
	)
	fmt.Println(SPRING, SUMMER, AUTUMN, WINTER)

	// 以const代码块形式声明常量
	const (
		size    int64 = 4096
		i, j, s       = 13, 14, "bar" // 单行声明多个常量
	)

	//两个底层类型的数据类型不可以混在一个表达式中进行运算
	type myInt int
	const x myInt = 20
	// const y int = x + 5 //报错  cannot use x + 5 (constant 25 of type myInt) as int value in constant declaration
	var z int = 5
	//fmt.Println(z + x) //报错 invalid operation: z + x (mismatched types int and myInt)
	fmt.Println(z + int(x)) //类型转换后正常输出:25

	//隐式重复前一个非空表达式
	const (
		rx, book = "hello", 123
		ab, test
		mn, data
	)
	fmt.Println(rx, book, ab, test, mn, data) //hello 123 hello 123 hello 123

	//iota
	const (
		rx1, book1 = iota, iota + 5
		ab1, test1
		mn1, data1
	)
	fmt.Println(rx1, book1, ab1, test1, mn1, data1) //0 5 1 6 2 7

	//如果想要从 iota = 1 开始正式定义枚举常量
	const (
		_ = iota
		a1
		_ //跳过了2
		b1
	)
	fmt.Println(a1, b1) //1 3

	//也可以下面的写法
	const (
		a2 = iota + 1
		_  //跳过了2
		b2
	)
	fmt.Println(a2, b2) //1 3

	//按位运算
	const (
		Readable = 1 << iota
		Writable
		Executable
		None
	)
	num := 7                                                                                                        //0111
	fmt.Println(num&Readable, num&Writable, num&Executable, num&None)                                               // 1 2 4 0
	fmt.Println(num&Readable == Readable, num&Writable == Writable, num&Executable == Executable, num&None == None) //true true true false
}
